#include "SquareRender.h"
/**
 * 使用EBO的绘制方式
 */
namespace Sivin {
  SquareRender::SquareRender() {
    mShader = std::make_unique<Shader>("./../shader/square/vert.vs", "./../shader/square/frag.fs");
    mVertexData = {
        0.5f, 0.5f, 0.0f,  // 右上
        -0.5f, 0.5f, 0.0f, // 左上
        -0.5f, -0.5f, 0.0f,// 左下
        0.5f, -0.5f, 0.0f};// 右下

    mElementIndexArray = {
        0, 1, 2, // 第一个三角形
        0, 2, 3};// 第二个三角形
  }
  SquareRender::~SquareRender() {}

  void SquareRender::onGLInit() {
    mShader->init();
    glGenVertexArrays(1, &mVAO);

    GLuint vbo;
    glGenBuffers(1, &vbo);

    GLuint ebo;
    glGenBuffers(1, &ebo);

    //绑定VAO
    glBindVertexArray(mVAO);

    //这段代码可以放到绑定VAO前，但建议放到绑定VAO后面，
    //本质上VAO记录的是shader程序中顶点属性该如何从VBO中读取数据
    //glVertexAttribPointer操作，会记录当前绑定的vbo的指针
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(float) * mVertexData.size(), mVertexData.data(), GL_STATIC_DRAW);


    //绑定EBO，这段代码必须放到绑定VAO之后，否则VAO将无法记录EBO指针
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int) * mElementIndexArray.size(), mElementIndexArray.data(), GL_STATIC_DRAW);

    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void *) 0);

    //解绑
    glBindVertexArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    //这一步不能在解绑VAO之前解绑，它会清除掉绑定VAO上的EBO
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
  }

  void SquareRender::onRender() {
    mShader->start();
    glBindVertexArray(mVAO);

    //使用EBO绘制，最后一个参数表示的是EBO的指针偏移位置
    glDrawElements(GL_TRIANGLES, mElementIndexArray.size(), GL_UNSIGNED_INT, (void *) 0);

    //上面是使用绑定到当前的VAO中的EBO来绘制，如果不使用EBO，则应该经mElementIndexArray的数据指针传递给GPU
    //glDrawElements(GL_TRIANGLES, mVertexData.size(), GL_UNSIGNED_INT, mElementIndexArray.data());
    mShader->end();
  }

}// namespace Sivin